package middleware

import (
	"github.com/starmotioncf/common/log"
	"github.com/starmotioncf/soutchatinternal/constant"
	"github.com/starmotioncf/soutchatinternal/errcode"
	"github.com/starmotioncf/soutchatinternal/resp"
	"github.com/starmotioncf/soutchatpkg/jwt"
	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
)

// AuthMiddleware 登陆鉴权
type AuthMiddleware struct {
	jwt *jwt.JWT
}

func NewAuthMiddleware(jwt *jwt.JWT) *AuthMiddleware {
	return &AuthMiddleware{
		jwt: jwt,
	}
}

func (m *AuthMiddleware) ForceLoginHandler() func(ctx *gin.Context) {
	return m.handle(true)
}

func (m *AuthMiddleware) CheckLoginHandler() func(ctx *gin.Context) {
	return m.handle(false)
}

func (m *AuthMiddleware) handle(forceLogin bool) func(ctx *gin.Context) {
	return func(ctx *gin.Context) {
		tokenStr := ctx.Request.Header.Get("Authorization")
		if tokenStr == "" {
			if forceLogin {
				resp.Error(ctx, errcode.ErrToken)
				ctx.Abort()
				return
			}
			ctx.Next()
			return
		}
		tp, err := m.jwt.ValidateToken(tokenStr)
		if err != nil {
			log.WithContext(ctx).Error("Authorization token error", zap.String("url", ctx.Request.URL.String()), zap.String("token", tokenStr), zap.Error(err))
			if forceLogin {
				resp.Error(ctx, errcode.ErrTokenExpired)
				ctx.Abort()
				return
			}
			ctx.Next()
			return
		}
		//向context写入用户token信息
		ctx.Set(constant.CtxToken, tp)
		ctx.Next()
	}
}
